Introdução

Logo SUS

A sigla EPI significa ‘equipamento de proteção individual’, ele é um direito garantido pela Norma Regulamentadora NR06 do Ministério do Trabalho e Emprego (MTE), e é definido como: “todo dispositivo ou produto, de uso individual utilizado pelo trabalhador, destinado à proteção de riscos suscetíveis de ameaçar a segurança e a saúde no trabalho”.

Mesmo antes da pandemia, os EPI’s já eram bastante utilizados, principalmente em indústrias e outros postos de trabalho com maiores riscos ocupacionais. Porém, durante a pandemia não só o Brasil, como todo o restante do globo, passaram a estender essa prática de uso de EPI’s para praticamente toda a população.

São diversos os tipos de EPI’s, empregados entre os quais podemos citar os abaixo os mais populares:

Devido à alta na procura e utilização desses equipamentos no período, planos de logística passaram à ser traçados para garantir a proteção dos profissionais de saúde que atuam na linha de frente do enfretamente à COVID-19.

Nessa análise focaremos na distribuição realizada pelo ministério da saúde em todo o país que auxiliou e reforçou as redes de saúde dos estados e municípios no combate à pandemia.

Nosso objetivo será visualizar quais materiais foram mais vezes solicitados pelos estados até o dia 05/09/2021.

Importar Libs

Bibliotecas que usaremos.

  • plotly: Montagem de gráficos 3D interativos
  • tidyverse: Biblioteca com funcionalidades gerais para ciência de dados
  • ggrepel: Afastar rótulos de texto que podem ser sobreescrever
  • knitr: Geração de relatórios dinâmicos
  • kableExtra: Permite criação de tabelas HTML estilizadas
  • FactoMineR: Realizar a análise de correspondência simples

Importar base de dados

Origem da base de dados: https://opendatasus.saude.gov.br/dataset/distribuicao-de-equipamentos-de-protecao-individual-e-insumos-covid-19

Licenciamento: Os dados disponibilizados pelo Poder Executivo Federal em formato aberto são de livre utilização e reúso, observados os termos constantes do inc. IV do art 3º e do art. 4 do Decreto nº 8777/16.

Resumo dos dados da base

  • material: material de saúde entregue;

  • data.saida: data de saída para entrega;

  • n.pedido: número do pedido;

  • requisitante: Estado de destino;

  • unidade: unidade de medida;

  • quantidade: quantidade entregue;

  • status: status da entrega.

Corrigindo tipos de dados no dataframe

Ao observar nossa base de dados, veremos que os tipos vierão todos como “character”. vamos corrigi-los e realizar um sumário para verificar se tudo está correto agora.

  • factor: material, requisitante, status
  • numerical: quantidade
  • character: n.pedido, unidade
  • date: data.saida
                     material      data.saida           n.pedido                         requisitante 
 Álcool                  : 575   Min.   :2020-03-17   Length:7055        Outros Órgãos Federais:2041  
 Avental                 : 572   1st Qu.:2020-04-10   Class :character   São Paulo             : 211  
 Luva                    :1055   Median :2020-05-25   Mode  :character   Pará                  : 209  
 Máscara Cirúrgica       :1657   Mean   :2020-07-03                      Acre                  : 206  
 Máscara N95             :1258   3rd Qu.:2020-08-27                      Santa Catarina        : 204  
 Óculos e Protetor Facial:1080   Max.   :2021-05-26                      Tocantins             : 204  
 Sapatilha e Touca       : 858                                           (Other)               :3980  
   unidade            quantidade            status    
 Length:7055        Min.   :       1   Entregue:7055  
 Class :character   1st Qu.:     400                  
 Mode  :character   Median :    3450                  
                    Mean   :   52459                  
                    3rd Qu.:   23800                  
                    Max.   :14954000                  
                    NA's   :122                       

Pré-Análise dos dados

Primeiro verificaremos se todas as solicitações analisadas estão com o status de “Entregue”.

[1] "Entregue"

Já podemos ter um insight que todas as solicitações realizadas aqui estão cumpridas, sem necessidade de análises adicionais desse ponto.

Escolha dos atributos para análise

Tendo em vista que nosso objetivo é analisar somente a quantidade de solicitações para os estados ao longo do tempo, podemos selecionar as variáveis “material” e “requisitante” para esse fim.

                     material                    requisitante 
 Álcool                  : 575   Outros Órgãos Federais:2041  
 Avental                 : 572   São Paulo             : 211  
 Luva                    :1055   Pará                  : 209  
 Máscara Cirúrgica       :1657   Acre                  : 206  
 Máscara N95             :1258   Santa Catarina        : 204  
 Óculos e Protetor Facial:1080   Tocantins             : 204  
 Sapatilha e Touca       : 858   (Other)               :3980  

Veja bem esse ponto: Ambas são categóricas.

Nesse caso podemos utilizar uma interessante análise não supervisionada para este caso: A análise de Correspondências Simples (Para mais detalhes, pode-se verificar um outro projeto meu explicando passo a passo como é realizada a análise de Correspondência Simples nesse link: Analise_Correspondencia_Covid).

Visualização mais elegante dos dados

Abaixo apenas uma visualização mais detalhista feitas atráves do kable que permite adicionar à tabela estilos à tabelas com nomenclatura do boostrap

material requisitante
Álcool Acre
Álcool Acre
Álcool Acre
Álcool Acre
Álcool Acre
Álcool Acre

Definição da Tabela de Frequências

O primeiro passo de uma análise de correspondência simples é a montagem de um tabela de frequências das nossas duas variáveis, ou seja, demonstrar quantas vezes uma aparece junto à outra.

                        
                         Álcool Avental Luva Máscara Cirúrgica Máscara N95 Óculos e Protetor Facial
  Acre                       15      20   36                40          47                       25
  Alagoas                    15      18   35                33          29                       24
  Amapá                      15      13   32                39          27                       30
  Amazonas                   15      25   30                34          27                       29
  Bahia                      16      17   34                38          25                       32
  Ceará                      15      15   37                39          29                       31
  Distrito Federal           14      14   29                25          24                       17
  Espírito Santo             16      15   35                41          26                       27
  Goiás                      15      16   33                38          30                       29
  Maranhão                   16      14   36                41          34                       29
  Mato Grosso                15      18   34                42          28                       27
  Mato Grosso do Sul         16      18   33                36          30                       30
  Minas Gerais               16      13   32                38          31                       26
  Outros Órgãos Federais    129     169  141               615         439                      326
  Pará                       17      18   37                50          32                       30
  Paraíba                    18      15   37                36          27                       30
  Paraná                     19      13   32                38          31                       28
  Pernambuco                 15      11   35                36          27                       27
  Piauí                      15      15   35                40          31                       29
  Rio de Janeiro             16       9   38                31          25                       26
  Rio Grande do Norte        16      15   35                40          26                       29
  Rio Grande do Sul          18      14   35                37          33                       30
  Rondônia                   16      14   34                38          27                       27
  Roraima                    19      11   29                38          26                       24
  Santa Catarina             18      15   34                46          35                       33
  São Paulo                  26      13   30                42          40                       32
  Sergipe                    18      12   34                37          26                       26
  Tocantins                  16      12   33                49          46                       27
                        
                         Sapatilha e Touca
  Acre                                  23
  Alagoas                               20
  Amapá                                 24
  Amazonas                              25
  Bahia                                 24
  Ceará                                 22
  Distrito Federal                      16
  Espírito Santo                        26
  Goiás                                 22
  Maranhão                              27
  Mato Grosso                           25
  Mato Grosso do Sul                    25
  Minas Gerais                          25
  Outros Órgãos Federais               222
  Pará                                  25
  Paraíba                               22
  Paraná                                25
  Pernambuco                            21
  Piauí                                 25
  Rio de Janeiro                        23
  Rio Grande do Norte                   21
  Rio Grande do Sul                     28
  Rondônia                              24
  Roraima                               21
  Santa Catarina                        23
  São Paulo                             28
  Sergipe                               25
  Tocantins                             21

Teste qui-Quadrado para verificar aderência da base de dados

Agora devemos verificar se as relações entre as nossas variáveis se dá ou não de forma aleatória.

Se nosso p-value resultante for menor que o grau de significância (nesse caso 0,5) existirá associação.

H0: (Hipótese Nula): Aleatoriedade de associação (Não há associação) H1: (Hipótese Alternativa): Existência de associação


    Pearson's Chi-squared test with simulated p-value (based on 2000 replicates)

data:  tab
X-squared = 279.32, df = NA, p-value = 0.0004998

Comprovado via teste estático, que existe relação de associação à um grau de significância de 0.5.

Mapa de Calor dos Resíduos Padronizados Ajustados

Sempre ao analisar um mapa perceptual (o output esperado de nossa modelo) devemos ter conosco um mapa com um os resíduos padronizados ajustados. Esse mapa tem a finalidade de explicitar as maiores relações e ajudará na interpretação do mapa.

Criação do Modelo de análise de Correspondências Simples

Feitos os diagnósticos, podemos então criar nosso modelo utilizando a tabela de frequências anterior. A saída dessa biblioteca é um mapa perceptual bem simples com as duas principais dimensões geradas, ou seja, as que capturam a maior parte da variância.

Podemos confirmar isso pelos eighvalues gerados e sua variância acumulada

        eigenvalue percentage of variance cumulative percentage of variance
dim 1 0.0325351275              82.175061                          82.17506
dim 2 0.0028309369               7.150192                          89.32525
dim 3 0.0020851058               5.266421                          94.59167
dim 4 0.0012359949               3.121794                          97.71347
dim 5 0.0005019746               1.267854                          98.98132
dim 6 0.0004033196               1.018678                         100.00000

Agora vamos guardar todas as coordendas geradas (linhas e colunas) num único objeto.

                               Dim 1        Dim 2        Dim 3         Dim 4         Dim 5
Acre                      0.04241871  0.041322875  0.181221090 -2.325041e-03 -0.0189450941
Alagoas                   0.15747457  0.076387614  0.063942860 -4.775720e-03  0.0289729192
Amapá                     0.10127833 -0.013956000 -0.054814187 -1.882617e-02 -0.0246387678
Amazonas                  0.10368860  0.197436229 -0.009974759  7.559079e-02 -0.0112735707
Bahia                     0.13470681  0.054636236 -0.067932827  9.877262e-05 -0.0011206100
Ceará                     0.13470351  0.014357961 -0.013740952 -5.053585e-02  0.0020784642
Distrito Federal          0.19102845  0.046849554  0.097560135  2.792679e-02  0.0535861417
Espírito Santo            0.13285973  0.010459207 -0.046613994 -1.691043e-02 -0.0064433283
Goiás                     0.09794016  0.031192707  0.003522198 -1.374109e-02 -0.0002383666
Maranhão                  0.10377431 -0.027107371  0.013702159 -1.512101e-02 -0.0434511678
Mato Grosso               0.09921928  0.061454899 -0.020148549 -1.663923e-02  0.0017076577
Mato Grosso do Sul        0.11544712  0.058528769 -0.004406782  3.027198e-02 -0.0248305305
Minas Gerais              0.09797808 -0.033342842  0.009113406  9.085886e-03 -0.0291215614
Outros Órgãos Federais   -0.27459902  0.002700964 -0.007192498 -1.044096e-03 -0.0001453190
Pará                      0.06940287  0.025443230 -0.019357842 -4.036872e-02  0.0330215699
Paraíba                   0.17570844  0.003077775 -0.021484593 -1.519839e-03  0.0293333072
Paraná                    0.10693605 -0.051632616 -0.008020573  4.582145e-02 -0.0031342324
Pernambuco                0.15362008 -0.048508855 -0.010281764 -5.056200e-02  0.0010418586
Piauí                     0.10659956  0.005889973 -0.002183944 -2.478820e-02 -0.0277665254
Rio de Janeiro            0.24286789 -0.085148538 -0.013612167 -3.627110e-02 -0.0271492250
Rio Grande do Norte       0.12898074  0.015721421 -0.037267173 -3.739398e-02  0.0384054930
Rio Grande do Sul         0.12939443 -0.032690643  0.002125021  3.562975e-02 -0.0500904105
Rondônia                  0.13478651 -0.004333742 -0.025258294 -9.646524e-03 -0.0039900210
Roraima                   0.10168904 -0.077690238 -0.031621015  3.862777e-02  0.0583535212
Santa Catarina            0.04956145 -0.026369810 -0.006912690 -1.356780e-02  0.0215246531
São Paulo                 0.05220766 -0.112128785  0.012107514  1.329184e-01  0.0126142632
Sergipe                   0.15917577 -0.050863717 -0.037849440  1.633369e-02  0.0003887115
Tocantins                -0.02542915 -0.092730566  0.116214468 -5.142789e-02  0.0095552474
Álcool                    0.14473295 -0.066297247 -0.012092705  8.202422e-02  0.0422676658
Avental                  -0.01116025  0.168332054  0.020991008  2.843808e-02  0.0145104409
Luva                      0.35176275 -0.004078271  0.022709999 -4.419654e-02  0.0047829903
Máscara Cirúrgica        -0.18288255 -0.011803118 -0.027863375 -2.963727e-02  0.0157233750
Máscara N95              -0.14496120 -0.027333207  0.082213942  6.491366e-03 -0.0111556810
Óculos e Protetor Facial -0.02264856  0.004509097 -0.053582681 -2.128077e-03 -0.0108842777
Sapatilha e Touca         0.07215680 -0.005581966 -0.033098872  3.081350e-02 -0.0441896278

Agora vamos criar um objeto com a quantidade de categorias de cada variável da base de dados.

    material requisitante 
           7           28 

Por fim juntaremos as coordenadas com as categorias

Ótimo, já temos tudo que precisamos para criação de nossos mapas.

Criando mapa perceptual bidimensional dos dados

Primeiro plotaremos os dados novamente num plano de 2 dimensões porém num mapa mais detalhado e amigável.

Criando mapa perceptual tridimensional dos dados

Por fim vamos plotar esses dados num gráfico com 3 dimensões dinâmico com o plotly.

LS0tDQp0aXRsZTogIkRpc3RyaWJ1acOnw6NvIGRlIEVxdWlwYW1lbnRvcyBkZSBQcm90ZcOnw6NvIEluZGl2aWR1YWwgZSBJbnN1bW9z4oCTIENvdmlkLSAxOSINCmF1dGhvcjogIk1hcmN1cyBWaW5pY2l1cyBkZSBGcmVpdGFzIENvc3RhIg0KZGF0ZTogIjA1IGRlIHNldGVtYnJvLCAyMDIxIiANCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMgSW50cm9kdcOnw6NvDQoNCiFbTG9nbyBTVVNdKGxvZ28tc3VzLXBuZy5wbmcpDQoNCkEgc2lnbGEgRVBJIHNpZ25pZmljYSAnZXF1aXBhbWVudG8gZGUgcHJvdGXDp8OjbyBpbmRpdmlkdWFsJywgZWxlIMOpIHVtIGRpcmVpdG8gZ2FyYW50aWRvIHBlbGEgTm9ybWEgUmVndWxhbWVudGFkb3JhIE5SMDYgZG8gTWluaXN0w6lyaW8gZG8gVHJhYmFsaG8gZSBFbXByZWdvIChNVEUpLCBlIMOpIGRlZmluaWRvIGNvbW86ICJ0b2RvIGRpc3Bvc2l0aXZvIG91IHByb2R1dG8sIGRlIHVzbyBpbmRpdmlkdWFsIHV0aWxpemFkbyBwZWxvIHRyYWJhbGhhZG9yLCBkZXN0aW5hZG8gw6AgcHJvdGXDp8OjbyBkZSByaXNjb3Mgc3VzY2V0w612ZWlzIGRlIGFtZWHDp2FyIGEgc2VndXJhbsOnYSBlIGEgc2HDumRlIG5vIHRyYWJhbGhvIi4NCg0KTWVzbW8gYW50ZXMgZGEgcGFuZGVtaWEsIG9zIEVQSSdzIGrDoSBlcmFtIGJhc3RhbnRlIHV0aWxpemFkb3MsIHByaW5jaXBhbG1lbnRlIGVtIGluZMO6c3RyaWFzIGUgb3V0cm9zIHBvc3RvcyBkZSB0cmFiYWxobyBjb20gbWFpb3JlcyByaXNjb3Mgb2N1cGFjaW9uYWlzLiBQb3LDqW0sIGR1cmFudGUgYSBwYW5kZW1pYSBuw6NvIHPDsyBvIEJyYXNpbCwgY29tbyB0b2RvIG8gcmVzdGFudGUgZG8gZ2xvYm8sIHBhc3NhcmFtIGEgZXN0ZW5kZXIgZXNzYSBwcsOhdGljYSBkZSB1c28gZGUgRVBJJ3MgcGFyYSBwcmF0aWNhbWVudGUgdG9kYSBhIHBvcHVsYcOnw6NvLiANCg0KU8OjbyBkaXZlcnNvcyBvcyB0aXBvcyBkZSBFUEnigJlzLCBlbXByZWdhZG9zIGVudHJlIG9zIHF1YWlzIHBvZGVtb3MgY2l0YXIgb3MgYWJhaXhvIG9zIG1haXMgcG9wdWxhcmVzOg0KDQoqIMOTY3Vsb3MgZGUgcHJvdGXDp8OjbzsNCiogUHJvdGV0b3JlcyBhdXJpY3VsYXJlczsNCiogTcOhc2NhcmFzOw0KKiBNYWdvdGVzOw0KKiBDYXBhY2V0ZXM7DQoqIEx1dmFzOw0KKiBCb3RhcywgDQoqIENpbnRvcyBkZSBzZWd1cmFuw6dhOw0KKiBQcm90ZXRvciBzb2xhci4NCg0KRGV2aWRvIMOgIGFsdGEgbmEgcHJvY3VyYSBlIHV0aWxpemHDp8OjbyBkZXNzZXMgZXF1aXBhbWVudG9zIG5vIHBlcsOtb2RvLCBwbGFub3MgZGUgbG9nw61zdGljYSBwYXNzYXJhbSDDoCBzZXIgdHJhw6dhZG9zIHBhcmEgZ2FyYW50aXIgYSBwcm90ZcOnw6NvIGRvcyBwcm9maXNzaW9uYWlzIGRlIHNhw7pkZSBxdWUgYXR1YW0gbmEgbGluaGEgZGUgZnJlbnRlIGRvIGVuZnJldGFtZW50ZSDDoCBDT1ZJRC0xOS4gDQoNCk5lc3NhIGFuw6FsaXNlIGZvY2FyZW1vcyBuYSBkaXN0cmlidWnDp8OjbyByZWFsaXphZGEgcGVsbyBtaW5pc3TDqXJpbyBkYSBzYcO6ZGUgZW0gdG9kbyBvIHBhw61zIHF1ZSBhdXhpbGlvdSBlIHJlZm9yw6dvdSBhcyByZWRlcyBkZSBzYcO6ZGUgZG9zIGVzdGFkb3MgZSBtdW5pY8OtcGlvcyBubyBjb21iYXRlIMOgIHBhbmRlbWlhLg0KDQpOb3NzbyBvYmpldGl2byBzZXLDoSB2aXN1YWxpemFyIHF1YWlzIG1hdGVyaWFpcyBmb3JhbSBtYWlzIHZlemVzIHNvbGljaXRhZG9zIHBlbG9zIGVzdGFkb3MgYXTDqSBvIGRpYSAwNS8wOS8yMDIxLiANCg0KDQojIyBJbXBvcnRhciBMaWJzDQoNCkJpYmxpb3RlY2FzIHF1ZSB1c2FyZW1vcy4NCg0KKiBwbG90bHk6IE1vbnRhZ2VtIGRlIGdyw6FmaWNvcyAzRCBpbnRlcmF0aXZvcw0KKiB0aWR5dmVyc2U6IEJpYmxpb3RlY2EgY29tIGZ1bmNpb25hbGlkYWRlcyBnZXJhaXMgcGFyYSBjacOqbmNpYSBkZSBkYWRvcw0KKiBnZ3JlcGVsOiBBZmFzdGFyIHLDs3R1bG9zIGRlIHRleHRvIHF1ZSBwb2RlbSBzZXIgc29icmVlc2NyZXZlcg0KKiBrbml0cjogR2VyYcOnw6NvIGRlIHJlbGF0w7NyaW9zIGRpbsOibWljb3MNCioga2FibGVFeHRyYTogUGVybWl0ZSBjcmlhw6fDo28gZGUgdGFiZWxhcyBIVE1MIGVzdGlsaXphZGFzDQoqIEZhY3RvTWluZVI6IFJlYWxpemFyIGEgYW7DoWxpc2UgZGUgY29ycmVzcG9uZMOqbmNpYSBzaW1wbGVzDQoNCmBgYHtyIGVjaG89RkFMU0V9DQoNCnBhY290ZXMgPC0gYygicGxvdGx5IiwidGlkeXZlcnNlIiwiZ2dyZXBlbCIsImtuaXRyIiwia2FibGVFeHRyYSIsIkZhY3RvTWluZVIiKQ0KDQojVmVyaWZpY2FyIHNlIHBhY290ZSBlc3TDoSBpbnN0YWxhZG8gZSBjYXJyZWdhciB0b2RvcyANCmZvciAoaSBpbiBwYWNvdGVzKXsNCiAgICAgaWYoISBpICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKCkpew0KICAgICAgICAgaW5zdGFsbC5wYWNrYWdlcyhpLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQ0KICAgICB9DQogICAgIHNhcHBseShwYWNvdGVzLCByZXF1aXJlLCBjaGFyYWN0ZXIgPSBUKSANCn0NCg0Kb3B0aW9ucyhnZ3JlcGVsLm1heC5vdmVybGFwcyA9IEluZikgI1Blcm1pdGlyIHF1ZSBtYWlzIHLDs3R1bG9zIHNlamFtIGFmYXN0YWRvcyANCmBgYA0KDQojIyBJbXBvcnRhciBiYXNlIGRlIGRhZG9zDQoNCk9yaWdlbSBkYSBiYXNlIGRlIGRhZG9zOg0KaHR0cHM6Ly9vcGVuZGF0YXN1cy5zYXVkZS5nb3YuYnIvZGF0YXNldC9kaXN0cmlidWljYW8tZGUtZXF1aXBhbWVudG9zLWRlLXByb3RlY2FvLWluZGl2aWR1YWwtZS1pbnN1bW9zLWNvdmlkLTE5DQoNCkxpY2VuY2lhbWVudG86DQpPcyBkYWRvcyBkaXNwb25pYmlsaXphZG9zIHBlbG8gUG9kZXIgRXhlY3V0aXZvIEZlZGVyYWwgZW0gZm9ybWF0byBhYmVydG8gc8OjbyBkZSBsaXZyZSB1dGlsaXphw6fDo28gZSByZcO6c28sIG9ic2VydmFkb3Mgb3MgdGVybW9zIGNvbnN0YW50ZXMgZG8gaW5jLiBJViBkbyBhcnQgM8K6IGUgZG8gYXJ0LiA0IGRvIERlY3JldG8gbsK6IDg3NzcvMTYuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQplcGlzIDwtIHJlYWQuY3N2KCdkaXN0cmlidWljYW9fZXBpLmNzdicsaGVhZGVyID0gVCxzZXA9IjsiKQ0KaGVhZChlcGlzKQ0KYGBgDQoNClJlc3VtbyBkb3MgZGFkb3MgZGEgYmFzZSANCg0KKiBtYXRlcmlhbDogbWF0ZXJpYWwgZGUgc2HDumRlIGVudHJlZ3VlOw0KDQoqIGRhdGEuc2FpZGE6IGRhdGEgZGUgc2HDrWRhIHBhcmEgZW50cmVnYTsNCg0KKiBuLnBlZGlkbzogbsO6bWVybyBkbyBwZWRpZG87DQoNCiogcmVxdWlzaXRhbnRlOiBFc3RhZG8gZGUgZGVzdGlubzsNCg0KKiB1bmlkYWRlOiB1bmlkYWRlIGRlIG1lZGlkYTsNCg0KKiBxdWFudGlkYWRlOiBxdWFudGlkYWRlIGVudHJlZ3VlOw0KDQoqIHN0YXR1czogc3RhdHVzIGRhIGVudHJlZ2EuDQoNCiMjIENvcnJpZ2luZG8gdGlwb3MgZGUgZGFkb3Mgbm8gIGRhdGFmcmFtZQ0KDQpBbyBvYnNlcnZhciBub3NzYSBiYXNlIGRlIGRhZG9zLCB2ZXJlbW9zIHF1ZSBvcyB0aXBvcyB2aWVyw6NvIHRvZG9zIGNvbW8gImNoYXJhY3RlciIuIHZhbW9zIGNvcnJpZ2ktbG9zIGUgcmVhbGl6YXIgdW0gc3Vtw6FyaW8gcGFyYSB2ZXJpZmljYXIgc2UgdHVkbyBlc3TDoSBjb3JyZXRvIGFnb3JhLg0KDQoqIGZhY3RvcjogbWF0ZXJpYWwsIHJlcXVpc2l0YW50ZSwgc3RhdHVzDQoqIG51bWVyaWNhbDogcXVhbnRpZGFkZQ0KKiBjaGFyYWN0ZXI6IG4ucGVkaWRvLCB1bmlkYWRlDQoqIGRhdGU6IGRhdGEuc2FpZGENCg0KYGBge3IgZWNobz1GQUxTRX0NCg0KZXBpcyRuLnBlZGlkbyA8LSBhcy5jaGFyYWN0ZXIoZXBpcyRuLnBlZGlkbykNCmVwaXMkcXVhbnRpZGFkZSA8LSBhcy5udW1lcmljKGVwaXMkcXVhbnRpZGFkZSkNCmVwaXMkbWF0ZXJpYWwgPC0gYXMuZmFjdG9yKGVwaXMkbWF0ZXJpYWwpDQplcGlzJHJlcXVpc2l0YW50ZSA8LSBhcy5mYWN0b3IoZXBpcyRyZXF1aXNpdGFudGUpDQplcGlzJHN0YXR1cyA8LSBhcy5mYWN0b3IoZXBpcyRzdGF0dXMpDQplcGlzJGRhdGEuc2FpZGEgPC0gYXMuRGF0ZS5jaGFyYWN0ZXIoZXBpcyRkYXRhLnNhaWRhLGZvcm1hdCA9IGMoIiVkLyVtLyVZIikpDQogIA0Kc3VtbWFyeShlcGlzKQ0KYGBgDQoNCiMjIFByw6ktQW7DoWxpc2UgZG9zIGRhZG9zDQoNClByaW1laXJvIHZlcmlmaWNhcmVtb3Mgc2UgdG9kYXMgYXMgc29saWNpdGHDp8O1ZXMgYW5hbGlzYWRhcyBlc3TDo28gY29tIG8gc3RhdHVzIGRlICJFbnRyZWd1ZSIuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQoNCmFzLmNoYXJhY3Rlcih1bmlxdWUodW5saXN0KGVwaXNbLGMoJ3N0YXR1cycpXSkpKQ0KDQpgYGANCg0KSsOhIHBvZGVtb3MgdGVyIHVtIGluc2lnaHQgcXVlIHRvZGFzIGFzIHNvbGljaXRhw6fDtWVzIHJlYWxpemFkYXMgYXF1aSBlc3TDo28gY3VtcHJpZGFzLCBzZW0gbmVjZXNzaWRhZGUgZGUgYW7DoWxpc2VzIGFkaWNpb25haXMgZGVzc2UgcG9udG8uDQoNCg0KIyMgRXNjb2xoYSBkb3MgYXRyaWJ1dG9zIHBhcmEgYW7DoWxpc2UNCg0KVGVuZG8gZW0gdmlzdGEgcXVlIG5vc3NvIG9iamV0aXZvIMOpIGFuYWxpc2FyIHNvbWVudGUgYSBxdWFudGlkYWRlIGRlIHNvbGljaXRhw6fDtWVzIHBhcmEgb3MgZXN0YWRvcyBhbyBsb25nbyBkbyB0ZW1wbywNCnBvZGVtb3Mgc2VsZWNpb25hciBhcyB2YXJpw6F2ZWlzICJtYXRlcmlhbCIgZSAicmVxdWlzaXRhbnRlIiBwYXJhIGVzc2UgZmltLg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KZXBpcyA8LSBlcGlzWyxjKCdtYXRlcmlhbCcsJ3JlcXVpc2l0YW50ZScpXQ0KDQpzdW1tYXJ5KGVwaXMpDQpgYGANCg0KVmVqYSBiZW0gZXNzZSBwb250bzogQW1iYXMgc8OjbyBjYXRlZ8OzcmljYXMuDQoNCk5lc3NlIGNhc28gcG9kZW1vcyB1dGlsaXphciB1bWEgaW50ZXJlc3NhbnRlIGFuw6FsaXNlIG7Do28gc3VwZXJ2aXNpb25hZGEgcGFyYSBlc3RlIGNhc286IEEgYW7DoWxpc2UgZGUgQ29ycmVzcG9uZMOqbmNpYXMgU2ltcGxlcyAoUGFyYSBtYWlzIGRldGFsaGVzLCBwb2RlLXNlIHZlcmlmaWNhciB1bSBvdXRybyBwcm9qZXRvIG1ldSBleHBsaWNhbmRvIHBhc3NvIGEgcGFzc28gY29tbyDDqSByZWFsaXphZGEgYSBhbsOhbGlzZSBkZSBDb3JyZXNwb25kw6puY2lhIFNpbXBsZXMgbmVzc2UgbGluazogW0FuYWxpc2VfQ29ycmVzcG9uZGVuY2lhX0NvdmlkXShodHRwczovL2dpdGh1Yi5jb20vTWFyY3VzLVYtRnJlaXRhcy9BbmFsaXNlX0NvcnJlc3BvbmRlbmNpYV9Db3ZpZCkpLg0KDQojIyBWaXN1YWxpemHDp8OjbyBtYWlzIGVsZWdhbnRlIGRvcyBkYWRvcyANCg0KQWJhaXhvIGFwZW5hcyB1bWEgdmlzdWFsaXphw6fDo28gbWFpcyBkZXRhbGhpc3RhIGZlaXRhcyBhdHLDoXZlcyBkbyBrYWJsZSBxdWUgcGVybWl0ZSBhZGljaW9uYXIgw6AgdGFiZWxhIGVzdGlsb3Mgw6AgdGFiZWxhcyBjb20gbm9tZW5jbGF0dXJhIGRvIFtib29zdHJhcF0oaHR0cHM6Ly9nZXRib290c3RyYXAuY29tLykNCg0KYGBge3IgZWNobz1GQUxTRX0NCmhlYWQoZXBpcykgJT4lIA0KICBrYWJsZSgpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLCANCiAgICAgICAgICAgICAgICBmb250X3NpemUgPSAxMikNCmBgYA0KIyMgRGVmaW5pw6fDo28gZGEgVGFiZWxhIGRlIEZyZXF1w6puY2lhcw0KDQpPIHByaW1laXJvIHBhc3NvIGRlIHVtYSBhbsOhbGlzZSBkZSBjb3JyZXNwb25kw6puY2lhIHNpbXBsZXMgw6kgYSBtb250YWdlbSBkZSB1bSB0YWJlbGEgZGUgZnJlcXXDqm5jaWFzDQpkYXMgbm9zc2FzIGR1YXMgdmFyacOhdmVpcywgb3Ugc2VqYSwgZGVtb25zdHJhciBxdWFudGFzIHZlemVzIHVtYSBhcGFyZWNlIGp1bnRvIMOgIG91dHJhLg0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KdGFiIDwtIHRhYmxlKGVwaXMkcmVxdWlzaXRhbnRlLA0KICAgICAgICAgICAgIGVwaXMkbWF0ZXJpYWwpIA0KDQp0YWINCmBgYA0KIyMgVGVzdGUgcXVpLVF1YWRyYWRvIHBhcmEgdmVyaWZpY2FyIGFkZXLDqm5jaWEgZGEgYmFzZSBkZSBkYWRvcw0KDQpBZ29yYSBkZXZlbW9zIHZlcmlmaWNhciBzZSBhcyByZWxhw6fDtWVzIGVudHJlIGFzIG5vc3NhcyB2YXJpw6F2ZWlzIHNlIGTDoSBvdSBuw6NvIGRlIGZvcm1hIGFsZWF0w7NyaWEuDQoNClNlIG5vc3NvIHAtdmFsdWUgcmVzdWx0YW50ZSBmb3IgbWVub3IgcXVlIG8gZ3JhdSBkZSBzaWduaWZpY8OibmNpYSAobmVzc2UgY2FzbyAwLDUpIGV4aXN0aXLDoSBhc3NvY2lhw6fDo28uDQoNCkgwOiAoSGlww7N0ZXNlIE51bGEpOiBBbGVhdG9yaWVkYWRlIGRlIGFzc29jaWHDp8OjbyAoTsOjbyBow6EgYXNzb2NpYcOnw6NvKQ0KSDE6ICAoSGlww7N0ZXNlIEFsdGVybmF0aXZhKTogRXhpc3TDqm5jaWEgZGUgYXNzb2NpYcOnw6NvDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpxdWkyIDwtIGNoaXNxLnRlc3QodGFiLHNpbXVsYXRlLnAudmFsdWUgPSBUKQ0KcXVpMg0KDQpgYGANCkNvbXByb3ZhZG8gdmlhIHRlc3RlIGVzdMOhdGljbywgcXVlIGV4aXN0ZSByZWxhw6fDo28gZGUgYXNzb2NpYcOnw6NvIMOgIHVtIGdyYXUgZGUgc2lnbmlmaWPDom5jaWEgZGUgMC41Lg0KDQojIyBNYXBhIGRlIENhbG9yIGRvcyBSZXPDrWR1b3MgUGFkcm9uaXphZG9zIEFqdXN0YWRvcw0KDQpTZW1wcmUgYW8gYW5hbGlzYXIgdW0gbWFwYSBwZXJjZXB0dWFsIChvIG91dHB1dCBlc3BlcmFkbyBkZSBub3NzYSBtb2RlbG8pIGRldmVtb3MgdGVyIGNvbm9zY28gdW0gbWFwYSBjb20gdW0gb3MgcmVzw61kdW9zIHBhZHJvbml6YWRvcyBhanVzdGFkb3MuIEVzc2UgbWFwYSB0ZW0gYSBmaW5hbGlkYWRlIGRlIGV4cGxpY2l0YXIgYXMgbWFpb3JlcyByZWxhw6fDtWVzIGUgYWp1ZGFyw6EgbmEgaW50ZXJwcmV0YcOnw6NvIGRvIG1hcGEuDQoNCmBgYHtyIGVjaG89RkFMU0V9DQoNCiMgTWFwYSBkZSBjYWxvciBkb3MgcmVzw61kdW9zIHBhZHJvbml6YWRvcyBhanVzdGFkb3MNCmRhdGEuZnJhbWUocXVpMiRzdGRyZXMpICU+JQ0KICByZW5hbWUocmVxdWlzaXRhbnRlID0gMSwNCiAgICAgICAgIG1hdGVyaWFsID0gMikgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSByZXF1aXNpdGFudGUsIHkgPSBtYXRlcmlhbCwgZmlsbCA9IEZyZXEsIGxhYmVsID0gcm91bmQoRnJlcSwzKSkpICsNCiAgZ2VvbV90aWxlKCkgKw0KICBnZW9tX3RleHQoc2l6ZSA9IDMsIGFuZ2xlID0gOTApICsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93ID0gIiM0NDAxNTRGRiIsIA0KICAgICAgICAgICAgICAgICAgICAgICBtaWQgPSAid2hpdGUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICIjRkRFNzI1RkYiLA0KICAgICAgICAgICAgICAgICAgICAgICBtaWRwb2ludCA9IDApICsNCiAgbGFicyh4ID0gTlVMTCwgeSA9IE5VTEwpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCANCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdCgid2hpdGUiKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkNCg0KYGBgDQoNCiMjIENyaWHDp8OjbyBkbyBNb2RlbG8gZGUgYW7DoWxpc2UgZGUgQ29ycmVzcG9uZMOqbmNpYXMgU2ltcGxlcw0KDQpGZWl0b3Mgb3MgZGlhZ27Ds3N0aWNvcywgcG9kZW1vcyBlbnTDo28gY3JpYXIgbm9zc28gbW9kZWxvIHV0aWxpemFuZG8gYSB0YWJlbGEgZGUgZnJlcXXDqm5jaWFzIGFudGVyaW9yLg0KQSBzYcOtZGEgZGVzc2EgYmlibGlvdGVjYSDDqSB1bSBtYXBhIHBlcmNlcHR1YWwgYmVtIHNpbXBsZXMgY29tIGFzIGR1YXMgcHJpbmNpcGFpcyBkaW1lbnPDtWVzIGdlcmFkYXMsIG91IHNlamEsIGFzIHF1ZSBjYXB0dXJhbSBhIG1haW9yIHBhcnRlIGRhIHZhcmnDom5jaWEuIA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KbW9kZWxvIDwtIENBKHRhYikNCmBgYA0KUG9kZW1vcyBjb25maXJtYXIgaXNzbyBwZWxvcyBlaWdodmFsdWVzIGdlcmFkb3MgZSBzdWEgdmFyacOibmNpYSBhY3VtdWxhZGEgIA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KbW9kZWxvJGVpZw0KYGBgDQpBZ29yYSB2YW1vcyBndWFyZGFyIHRvZGFzIGFzIGNvb3JkZW5kYXMgZ2VyYWRhcyAobGluaGFzIGUgY29sdW5hcykgbnVtIMO6bmljbyBvYmpldG8uIA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY29vcmRlbmFkYXMgPC0gcmJpbmQobW9kZWxvJHJvdyRjb29yZCwgbW9kZWxvJGNvbCRjb29yZCkNCmNvb3JkZW5hZGFzDQpgYGANCkFnb3JhIHZhbW9zIGNyaWFyIHVtIG9iamV0byBjb20gYSBxdWFudGlkYWRlIGRlIGNhdGVnb3JpYXMgZGUgY2FkYSB2YXJpw6F2ZWwgZGEgYmFzZSBkZSBkYWRvcy4NCg0KYGBge3IgZWNobz1GQUxTRX0NCnZhcmlhdmVpcyA8LSBhcHBseShlcGlzLA0KICAgICAgICAgICAgICAgIE1BUkdJTiA9ICAyLA0KICAgICAgICAgICAgICAgIEZVTiA9IGZ1bmN0aW9uKHgpIG5sZXZlbHMoYXMuZmFjdG9yKHgpKSkNCnZhcmlhdmVpcw0KDQpgYGANClBvciBmaW0ganVudGFyZW1vcyBhcyBjb29yZGVuYWRhcyBjb20gYXMgY2F0ZWdvcmlhcw0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY29vcmRlbmFkYXNfdmFyaWF2ZWlzIDwtIGRhdGEuZnJhbWUoY29vcmRlbmFkYXMsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJpYXZlbCA9IHJlcChuYW1lcyh2YXJpYXZlaXMpLCB2YXJpYXZlaXMpKQ0KY29vcmRlbmFkYXNfdmFyaWF2ZWlzDQpgYGANCsOTdGltbywgasOhIHRlbW9zIHR1ZG8gcXVlIHByZWNpc2Ftb3MgcGFyYSBjcmlhw6fDo28gZGUgbm9zc29zIG1hcGFzLg0KDQojIyBDcmlhbmRvIG1hcGEgcGVyY2VwdHVhbCBiaWRpbWVuc2lvbmFsIGRvcyBkYWRvcw0KDQpQcmltZWlybyBwbG90YXJlbW9zIG9zIGRhZG9zIG5vdmFtZW50ZSBudW0gcGxhbm8gZGUgMiBkaW1lbnPDtWVzIHBvcsOpbSBudW0gbWFwYSBtYWlzIGRldGFsaGFkbyBlIGFtaWfDoXZlbC4gIA0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0KY29vcmRlbmFkYXNfdmFyaWF2ZWlzICU+JSANCiAgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIA0KICByZW5hbWUoY2F0ZWdvcmlhID0gMSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHggPSBEaW0uMSwgDQogICAgICAgICAgICAgeSA9IERpbS4yLCANCiAgICAgICAgICAgICBsYWJlbCA9IGNhdGVnb3JpYSwgDQogICAgICAgICAgICAgY29sb3IgPSB2YXJpYXZlbCwgDQogICAgICAgICAgICAgc2hhcGUgPSB2YXJpYXZlbCkpICsNCiAgZ2VvbV9wb2ludChzaXplID0gMykgKw0KICBnZW9tX2xhYmVsX3JlcGVsKCkgKw0KICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArDQogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAsIGxpbmV0eXBlID0gImRhc2hlZCIpICsNCiAgbGFicyh4ID0gcGFzdGUoIkRpbWVuc8OjbyAxOiIsIHBhc3RlMChyb3VuZChtb2RlbG8kZWlnWzEsMl0sIGRpZ2l0cyA9IDIpLCAiJSIpKSwNCiAgICAgICB5ID0gcGFzdGUoIkRpbWVuc8OjbyAyOiIsIHBhc3RlMChyb3VuZChtb2RlbG8kZWlnWzIsMl0sIGRpZ2l0cyA9IDIpLCAiJSIpKSkgKw0KICBzY2FsZV9jb2xvcl92aXJpZGlzX2QoKSArDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoIndoaXRlIiksDQogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdCgiTkEiKSwNCiAgICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfbGluZSgiZ3JheTk1IiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KYGBgDQojIyBDcmlhbmRvIG1hcGEgcGVyY2VwdHVhbCB0cmlkaW1lbnNpb25hbCBkb3MgZGFkb3MNCg0KUG9yIGZpbSB2YW1vcyBwbG90YXIgZXNzZXMgZGFkb3MgbnVtIGdyw6FmaWNvIGNvbSAzIGRpbWVuc8O1ZXMgZGluw6JtaWNvIGNvbSBvIHBsb3RseS4NCg0KYGBge3IgZWNobz1GQUxTRX0NCmNvb3JkZW5hZGFzX2xpbmhhcyA8LSBtb2RlbG8kcm93JGNvb3JkDQpjb29yZGVuYWRhc19saW5oYXMNCg0KIyBDYXB0dXJhbmRvIGFzIGNvb3JkZW5hZGFzIGRhcyBjYXRlZ29yaWFzIGRhIHZhcmnDoXZlbCBkaXNwb3N0YSBlbSBjb2x1bmENCmNvb3JkZW5hZGFzX2NvbHVuYXMgPC0gbW9kZWxvJGNvbCRjb29yZA0KY29vcmRlbmFkYXNfY29sdW5hcw0KDQptYXBhX3BlcmNlcHR1YWxfM0QgPC0gcGxvdF9seSgpIA0KDQojIEluc2VyaW5kbyBhcyBjb29yZGVuYWRhcyBkYXMgY2F0ZWdvcmlhcyBkYSB2YXJpw6F2ZWwgZGlzcG9zdGEgZW0gbGluaGENCm1hcGFfcGVyY2VwdHVhbF8zRCA8LSBhZGRfdHJhY2UobWFwYV9wZXJjZXB0dWFsXzNELCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9IGNvb3JkZW5hZGFzX2xpbmhhc1ssMV0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gY29vcmRlbmFkYXNfbGluaGFzWywyXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeiA9IGNvb3JkZW5hZGFzX2xpbmhhc1ssM10sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSAidGV4dCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJzY2F0dGVyM2QiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcm93bmFtZXMoY29vcmRlbmFkYXNfbGluaGFzKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dGZvbnQgPSBsaXN0KGNvbG9yID0gIiM0NDAxNTRGRiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvd2xlZ2VuZCA9IEZBTFNFKSANCg0KIyBJbnNlcmluZG8gYXMgY29vcmRlbmFkYXMgZGFzIGNhdGVnb3JpYXMgZGEgdmFyacOhdmVsIGRpc3Bvc3RhIGVtIGNvbHVuYQ0KbWFwYV9wZXJjZXB0dWFsXzNEIDwtIGFkZF90cmFjZShtYXBhX3BlcmNlcHR1YWxfM0QsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gY29vcmRlbmFkYXNfY29sdW5hc1ssMV0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gY29vcmRlbmFkYXNfY29sdW5hc1ssMl0sIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6ID0gY29vcmRlbmFkYXNfY29sdW5hc1ssM10sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUgPSAidGV4dCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPSJzY2F0dGVyM2QiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcm93bmFtZXMoY29vcmRlbmFkYXNfY29sdW5hcyksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRmb250ID0gbGlzdChjb2xvciA9ICIjMjg3QzhFRkYiKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRSkgDQoNCiMgSW5zZXJpbmRvIG8gbm9tZSBkb3MgZWl4b3MgKERpbWVuc8OjbyAxLCBEaW1lbnPDo28gMiBlIERpbWVuc8OjbyAzKQ0KbWFwYV9wZXJjZXB0dWFsXzNEIDwtIGxheW91dChtYXBhX3BlcmNlcHR1YWxfM0QsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2VuZSA9IGxpc3QoeGF4aXMgPSBsaXN0KHRpdGxlID0gY29sbmFtZXMoY29vcmRlbmFkYXNfbGluaGFzKVsxXSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSBjb2xuYW1lcyhjb29yZGVuYWRhc19saW5oYXMpWzJdKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHpheGlzID0gbGlzdCh0aXRsZSA9IGNvbG5hbWVzKGNvb3JkZW5hZGFzX2xpbmhhcylbM10pLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwZWN0bW9kZSA9ICJkYXRhIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IGxpc3QobCA9IDAsIHIgPSAwLCBiID0gMCwgdCA9IDApKQ0KDQptYXBhX3BlcmNlcHR1YWxfM0QNCmBgYA0KDQoNCg==